# coding=utf-8
import socket
import threading
import exceptions
import contextlib
import md5
import random
import string

class im_server(object):
	def __init__(self):
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		self.sock.bind(('', 6666))
		self.sock.listen(100)
		self.conns = []
	
	def run(self):
		while True:
			conn,add = self.sock.accept()
			newThread = connThread(conn,self)
			newThread.start()
			self.addToList(newThread)
	
	def hasNickName(self, nickName):
		print 'find %s' %nickName
		for n in self.conns:
			print n.nickName
			if n.nickName == nickName:
				return n
		return False
	
	def addToList(self, conn):
		self.conns.append(conn)
		print 'new connection,total:%d' %len(self.conns)
	
	def removeFromList(self, conn):
		try:
			self.conns.remove(conn)
		except:
			print 'can not remove'
		print 'close conn,there is %d' %len(self.conns)

class connThread(threading.Thread):
	def __init__(self, conn, server):
		threading.Thread.__init__(self)
		self.conn = conn
		self.server = server
		self.nickName = False
		self.key = ''

	def run(self):
		isGoOn = True
		while isGoOn:
			try:
				request = self.conn.recv(1024).strip()
				reStr = ''
				if '<policy-file-request/>\0' == request:
					self.conn.send('<cross-domain-policy><site-control permitted-cross-domain-policies="all"/><allow-access-from domain="*" to-ports="9999,6666"/></cross-domain-policy>\0')
				request = request[:-1]
				request = request.split('|')
				print 'received:%s' %request[0]
				if len(request) == 1:
					if 'G' == request[0]:
						self.key = getKey()
						reStr = '%s|G' %self.key
					else:
						reStr = 'go out'
				else:
					if 'J' == request[1]:
						if self.key == request[0]:
							self.nickName = request[2]
							reStr = '%s|J|88' %request[2]
							self.key = getKey()
							reStr = '%s|J|%s|88' %(self.key, request[2])
						else:
							reStr = 'key error'
					elif 'M' == request[1]:
						if self.key == request[0]:
							sendTo = self.server.hasNickName(request[2])
							if False == sendTo:
								reStr = 'user %s is not found' %request[2]
							else:
								self.key = getKey()
								reStr = '%s|M|%s|%s' %(self.key, self.nickName, request[3])
								sendTo.send(reStr)
					else:
						reStr = 'please go out'
				self.send('%s\0' %reStr)
			except Exception, e:
				print 'has exception. break\n'
				isGoOn = False
		print 'connect over'
		self.server.removeFromList(self)

	def send(self,str):
		self.conn.send('%s\0' %str)

def getKey():
	m = md5.new()
	m.update(string.join(random.sample(['z','y','x','w','v','u','t','s','r','q','p','o','n','m','l','k','j','i','h','g','f','e','d','c','b','a'], 5)).replace(' ',''))
	return m.hexdigest()

def main():
	im_server().run()

if __name__ == '__main__':
    main()				